home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / fredfish / 1050.lha / Programs / Binary_dt / source / dispatch.c < prev    next >
C/C++ Source or Header  |  1994-12-28  |  32KB  |  1,035 lines

  1. /*
  2. ** $PROJECT: binary.datatype
  3. **
  4. ** $VER: dispatch.c 39.6 (28.12.94)
  5. **
  6. ** by
  7. **
  8. ** Stefan Ruppert , Windthorststraße 5 , 65439 Flörsheim , GERMANY
  9. **
  10. ** (C) Copyright 1994
  11. ** All Rights Reserved !
  12. **
  13. ** $HISTORY:
  14. **
  15. ** 28.12.94 : 039.006 : now it's a base datatype and no async layout is needed
  16. ** 24.11.94 : 039.005 : memory handling improved, layout only performed if needed
  17. ** 18.11.94 : 039.004 : added PREFS file
  18. ** 16.11.94 : 039.003 : BDTDH_NONE now works
  19. ** 15.11.94 : 039.002 : added BDTA_BytesPerLine,BDTA_DisplayHex and BDTA_ShowASCII attrs
  20. ** 13.11.94 : 039.001 : initial
  21. */
  22.  
  23. /* ------------------------------- include -------------------------------- */
  24.  
  25. #include "classbase.h"
  26.  
  27. /* ------------------------------- autodoc -------------------------------- */
  28.  
  29. /*FS*/ /*"AutoDoc"*/
  30. /*GB*** binary.datatype/binary.datatype **************************************
  31. *
  32. *    NAME
  33. *        binary.datatype -- data type for any binary file
  34. *
  35. *    FUNCTION
  36. *        The binary data type, a base-class of all binary data, is used to
  37. *        load any binary file and displays the contents of the file in hex
  38. *        format.
  39. *
  40. *    PREFS
  41. *        The data type tries to load the prefs file "ENV:binary.prefs" on
  42. *        each OM_NEW method to set up the attributes !
  43. *        This prefs file has the following format :
  44. *        line = NOASCII     |  - set BDTA_ShowASCII to FALSE
  45. *               NOWRAP      |  - set BDTA_DisplayWrap to FALSE
  46. *               NONE        |  - set BDTA_DisplayHex to BDTDH_NONE
  47. *               BYTE        |  - set BDTA_DisplayHex to BDTDH_BYTE
  48. *               WORD        |  - set BDTA_DisplayHex to BDTDH_WORD
  49. *               LONG        |  - set BDTA_DisplayHex to BDTDH_LONG
  50. *               BYTES <bpl>    - set BDTA_BytesPerLine to <bpl> bytes
  51. *
  52. *    METHODS
  53. *        OM_NEW -- Create a new text object from a binary file in hex mode.
  54. *
  55. *        OM_DISPOSE -- dispose a object
  56. *
  57. *        OM_GET -- get a attribute of the object
  58. *
  59. *        OM_SET -- set attributes of the object
  60. *
  61. *        OM_UPDATE -- update some attributes of the object
  62. *
  63. *        GM_LAYOUT -- Method to layout the hex text
  64. *
  65. *        GM_RENDER -- draw the object
  66. *
  67. *        DTM_WRITE -- DTWM_RAW mode is supported
  68. *
  69. *    TAGS
  70. *        BDTA_Buffer -- (UBYTE *) pointer to the buffer, which should be
  71. *            displayed.
  72. *            Applicability is (ISG).
  73. *
  74. *        BDTA_BufferLen -- (ULONG) length of the buffer supplied with
  75. *            BDTA_Buffer tag. This must be given if the buffer tag is
  76. *            specified.
  77. *            Applicability is (ISG).
  78. *
  79. *        BDTA_BytesPerLine -- (UWORD) number of bytes per line.
  80. *            If BDTA_DisplayHex is BDTDH_WORD it must be a multiply of 2,
  81. *            if it is BDTDH_LONG it must be a multiply of 4 !
  82. *            Default is 32.
  83. *            Applicability is (ISGNU).
  84. *
  85. *        BDTA_DisplayHex -- (UWORD) type of the display. The following types
  86. *            are supported : BDTDH_NONE  - displays no hex values
  87. *                            BDTDH_BYTE  - displays each byte in hex ( 8 bit)
  88. *                            BDTDH_WORD  - displays each word in hex (16 bit)
  89. *                            BDTDH_LONG  - displays each long in hex (32 bit)
  90. *            Default is BDTDH_LONG.
  91. *            Applicability is (ISGNU).
  92. *
  93. *        BDTA_ShowASCII -- (BOOL) display at the end of the line the
  94. *            appropriate ASCII string !
  95. *            Default is TRUE.
  96. *            Applicability is (ISGNU).
  97. *
  98. *        BDTA_DisplayWrap -- (BOOL) the BDTA_BytesPerLine are ignored and the
  99. *            byte number is retrieved from the object width !
  100. *            Default is TRUE.
  101. *            Applicability is (ISGNU).
  102. *
  103. *    BUGS
  104. *        At the moment proportional fonts can't be handled.
  105. *
  106. *    SEE ALSO
  107. *        datatypesclass (where ?)
  108. *
  109. ******************************************************************************
  110. *
  111. */
  112. /*FE*/
  113.  
  114. /* ------------------------------- defines -------------------------------- */
  115.  
  116. #define G(o)               ((struct Gadget *) (o))
  117. #define GPR(msg)           ((struct gpRender *) (msg))
  118. #define SET(msg)           ((struct opSet *) (msg))
  119. #define WRMSG(msg)         ((struct dtWrite *) (msg))
  120.  
  121.  
  122. /* ---------------------------- instance data ----------------------------- */
  123.  
  124. struct BinaryData
  125. {
  126.    UBYTE *bd_Buffer;
  127.    ULONG bd_BufferLen;
  128.  
  129.    UWORD bd_Flags;
  130.    UWORD bd_BytesPerLine;
  131.    UWORD bd_DisplayHex;
  132.  
  133.    UWORD bd_NumGroups;
  134.    UWORD bd_LineBytes;
  135.  
  136.    UWORD bd_LineBufferLen;
  137.    UBYTE *bd_LineBuffer;
  138.  
  139.    ULONG bd_OldX;
  140.    ULONG bd_OldY;
  141.  
  142.    /* font support */
  143.    struct TextFont *bd_Font;
  144.    struct TextAttr bd_TextAttr;
  145.    UBYTE bd_FontName[MAXFONTNAME];
  146.  
  147.    UBYTE bd_Name[256];
  148.  
  149.    /* list of gadget objects */
  150.    struct List bd_ObjectList;
  151. };
  152.  
  153. #define BDF_SHOWASCII         (1<<0)
  154. #define BDF_ALLOCATED         (1<<1)
  155. #define BDF_DISPLAYWRAP       (1<<2)
  156.  
  157. /* ---------------------------- constant data ----------------------------- */
  158.  
  159. const ULONG methods[] = {
  160.    OM_NEW,
  161.    OM_DISPOSE,
  162.    OM_GET,
  163.    OM_SET,
  164.    OM_UPDATE,
  165.    GM_LAYOUT,
  166.    GM_RENDER,
  167.    DTM_WRITE,
  168.    ~0};
  169.  
  170. /* ------------------------------ init class ------------------------------ */
  171.  
  172. /*FS*/ /*"LibCall Class *initClass(REGA6 struct ClassBase *cb)"*/
  173. LibCall Class *initClass(REGA6 struct ClassBase *cb)
  174. {
  175.    Class *cl;
  176.  
  177.    D(bug("init binary.datatype !\n"));
  178.  
  179.    if((cl = MakeClass("binary.datatype","datatypesclass",NULL,sizeof(struct BinaryData),0)))
  180.    {
  181.       cl->cl_Dispatcher.h_Entry = (HOOKFUNC) dispatch;
  182.       cl->cl_UserData = (ULONG) cb;
  183.  
  184.       AddClass(cl);
  185.    }
  186.  
  187.    return(cl);
  188. }
  189. /*FE*/
  190.  
  191. /* -------------------------- support functions --------------------------- */
  192.  
  193. /*FS*/ ULONG notifyAttrChanges(Object * obj, void * ginfo, ULONG flags, ULONG tag1,...)
  194. {
  195.     return(DoMethod(obj, OM_NOTIFY, &tag1, ginfo, flags));
  196. }
  197. /*FE*/
  198.  
  199. /*FS*/ ULONG setSuperAttrs(Class *cl,Object * obj, void *ginfo,ULONG tag1,...)
  200. {
  201.     return(DoSuperMethod(cl,obj, OM_SET, &tag1, ginfo));
  202. }
  203. /*FE*/
  204.  
  205. /*FS*/ void readPrefs(struct ClassBase *cb,struct BinaryData *bd)
  206. {
  207.    BPTR fh;
  208.  
  209.    ENTERING;
  210.  
  211.    if((fh = Open("ENV:binary.prefs",MODE_OLDFILE)))
  212.    {
  213.       UBYTE buf[100];
  214.       STRPTR ptr;
  215.  
  216.       while((ptr = FGets(fh,buf,sizeof(buf)-1)))
  217.       {
  218.          if(!Strnicmp(ptr,"NOASCII",7))
  219.             bd->bd_Flags &= ~BDF_SHOWASCII;
  220.          else if(!Strnicmp(ptr,"NOWRAP",6))
  221.             bd->bd_Flags &= ~BDF_DISPLAYWRAP;
  222.          else if(!Strnicmp(ptr,"NONE",4))
  223.             bd->bd_DisplayHex = BDTDH_NONE;
  224.         else if(!Strnicmp(ptr,"WORD",4))
  225.             bd->bd_DisplayHex = BDTDH_WORD;
  226.          else if(!Strnicmp(ptr,"LONG",4))
  227.             bd->bd_DisplayHex = BDTDH_LONG;
  228.          else if(!Strnicmp(ptr,"BYTES",5))
  229.          {
  230.             LONG value = 32;
  231.             ptr += 5;
  232.             if(StrToLong(ptr,&value) > 0)
  233.                bd->bd_BytesPerLine = value;
  234.          } else if(!Strnicmp(ptr,"BYTE",4))
  235.             bd->bd_DisplayHex = BDTDH_BYTE;
  236.       }
  237.       Close(fh);
  238.    }
  239.  
  240.    LEAVING;
  241. }
  242. /*FE*/
  243.  
  244. /*FS*/ void useDefaultFont(struct ClassBase *cb,struct BinaryData *bd)
  245. {
  246.    struct TextFont *deffont;
  247.  
  248.    D(bug("using default font !\n"));
  249.  
  250.    #undef GfxBase
  251.    deffont = ((struct GfxBase *) cb->cb_GfxBase)->DefaultFont;
  252.    #define GfxBase cb->cb_GfxBase
  253.  
  254.    bd->bd_TextAttr.ta_YSize = deffont->tf_YSize;
  255.    bd->bd_TextAttr.ta_Style = FS_NORMAL;
  256.    bd->bd_TextAttr.ta_Flags = deffont->tf_Flags;
  257.    bd->bd_TextAttr.ta_Name  = bd->bd_FontName;
  258.    strcpy(bd->bd_TextAttr.ta_Name,deffont->tf_Message.mn_Node.ln_Name);
  259.  
  260.    bd->bd_Font = OpenFont(&bd->bd_TextAttr);
  261. }
  262. /*FE*/
  263.  
  264. /* --------------------------- class dispatcher --------------------------- */
  265.  
  266. /*FS*/ ClassCall ULONG dispatch(REGA0 Class *cl,REGA2 Object *obj,REGA1 Msg msg)
  267. {
  268.    struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  269.    struct BinaryData *bd;
  270.    ULONG retval = 0;
  271.  
  272.    switch(msg->MethodID)
  273.    {
  274.    case OM_NEW:
  275.       {
  276.          Object *newobj;
  277.          if((newobj = (Object *) DoSuperMethodA(cl,obj,msg)))
  278.          {
  279.             bd = INST_DATA(cl,newobj);
  280.  
  281.             /* set default setting */
  282.             bd->bd_BytesPerLine = 32;
  283.             bd->bd_DisplayHex   = BDTDH_LONG;
  284.             bd->bd_Flags        = BDF_SHOWASCII | BDF_DISPLAYWRAP;
  285.  
  286.             NewList(&bd->bd_ObjectList);
  287.  
  288.             /* read default user settings */
  289.             readPrefs(cb,bd);
  290.  
  291.             setattrs(cl,newobj,(struct opSet *) msg);
  292.  
  293.             /* use default textfont */
  294.             if(!bd->bd_Font)
  295.                useDefaultFont(cb,bd);
  296.  
  297.             /* if no buffer is provided , get the handle from the superclass
  298.                and load the file in the buffer */
  299.             if(!bd->bd_Buffer)
  300.             {
  301.                BPTR fh;
  302.                ULONG type;
  303.                LONG num;
  304.  
  305.                if(((num = GetDTAttrs((Object *) newobj,DTA_Handle     ,&fh,
  306.                                                        DTA_SourceType ,&type,
  307.                                                        TAG_DONE)) == 2) && fh)
  308.                {
  309.                   struct FileInfoBlock *fib;
  310.  
  311.                   D(bug("type : %ld\n",type));
  312.  
  313.                   switch(type)
  314.                   {
  315.                   case DTST_FILE:
  316.                      if((fib = AllocDosObject(DOS_FIB,NULL)))
  317.                      {
  318.                         if(ExamineFH(fh,fib) && fib->fib_Size > 0)
  319.                         {
  320.                            if((bd->bd_Buffer = AllocMem(fib->fib_Size,MEMF_ANY)))
  321.                            {
  322.                               bd->bd_Flags |= BDF_ALLOCATED;
  323.                               bd->bd_BufferLen = fib->fib_Size;
  324.                               Seek(fh,0,OFFSET_BEGINNING);
  325.                               Read(fh,bd->bd_Buffer,bd->bd_BufferLen);
  326.                            }
  327.                         }
  328.                      }
  329.                      FreeDosObject(DOS_FIB,fib);
  330.                      if(!NameFromFH(fh,bd->bd_Name,sizeof(bd->bd_Name)))
  331.                         strcpy(bd->bd_Name,"unknown");
  332.                      break;
  333.                   case DTST_RAM:
  334.                      strcpy(bd->bd_Name,"RAM");
  335.                      break;
  336.                   default:
  337.                      D(bug("not supported SourceType : %ld\n",type));
  338.                   }
  339.  
  340.                }
  341.             }
  342.  
  343.             if(bd->bd_Buffer)
  344.             {
  345.                retval = (ULONG) newobj;
  346.                ((struct ExtGadget *) newobj)->MoreFlags = GMORE_SCROLLRASTER;
  347.             } else  /* something was going wrong, thus dispose myself */
  348.             {
  349.                D(bug("binary.datatype error : %ld\n",IoErr()));
  350.                CoerceMethod(cl,(Object *) retval,OM_DISPOSE);
  351.             }
  352.          }
  353.       }
  354.       break;
  355.    case OM_DISPOSE:
  356.       bd = INST_DATA(cl,obj);
  357.  
  358.       if(bd->bd_Buffer && (bd->bd_Flags & BDF_ALLOCATED))
  359.          FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
  360.  
  361.       if(bd->bd_LineBuffer && bd->bd_LineBufferLen)
  362.          FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
  363.  
  364.       if(bd->bd_Font)
  365.          CloseFont(bd->bd_Font);
  366.  
  367. #ifdef EXPERIMENTAL
  368.       /* I don't know , how gadgets can be intergrated in a datatype ?
  369.        * If there is anybody who knows ? Let me know , please !
  370.        */
  371.       {
  372.          APTR gadobj;
  373.          /* dispose all objects from the list c*/
  374.          gadobj = bd->bd_ObjectList.lh_Head;
  375.          while((gadobj = NextObject(&gadobj)))
  376.          {
  377.             DoMethod(gadobj,OM_REMOVE);
  378.             if(G(gadobj)->GadgetRender)
  379.                DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
  380.             DoMethod(gadobj,OM_DISPOSE);
  381.          }
  382.       }
  383. #endif
  384.  
  385.       retval = DoSuperMethodA(cl,obj,msg);
  386.       break;
  387.    case OM_UPDATE:
  388.    case OM_SET:
  389.       if((retval = setattrs(cl,obj,(struct opSet *) msg)))
  390.          DoMethod(obj,GM_LAYOUT,((struct opSet *) msg)->ops_GInfo,TRUE);
  391.  
  392.       /* Pass the attributes to the super class and force a refresh
  393.        * if we need it */
  394.       if((retval += DoSuperMethodA (cl, obj, msg)) && (OCLASS (obj) == cl))
  395.       {
  396.          struct RastPort *rp;
  397.  
  398.          /* Get a pointer to the rastport */
  399.          if((rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo)))
  400.          {
  401.             struct gpRender gpr;
  402.  
  403.             /* Force a redraw */
  404.             gpr.MethodID   = GM_RENDER;
  405.             gpr.gpr_GInfo  = ((struct opSet *) msg)->ops_GInfo;
  406.             gpr.gpr_RPort  = rp;
  407.             gpr.gpr_Redraw = GREDRAW_UPDATE;
  408.             DoMethodA (obj, (Msg) &gpr);
  409.  
  410.             /* Release the temporary rastport */
  411.             ReleaseGIRPort (rp);
  412.          }
  413.  
  414.          retval = 0;
  415.       }
  416.       break;
  417.    case OM_GET:
  418.       if(!(retval = getattr(cl,obj,(struct opGet *) msg)))
  419.          retval = DoSuperMethodA(cl,obj,msg);
  420.       break;
  421.    case GM_LAYOUT:
  422.       /* Tell everyone that we are busy doing things */
  423.       notifyAttrChanges (obj, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
  424.                          GA_ID,       G(obj)->GadgetID,
  425.                          DTA_Busy,    TRUE,
  426.                          TAG_DONE);
  427.  
  428.       /* Let the super-class partake */
  429.       retval = DoSuperMethodA (cl, obj, msg);
  430.  
  431.       retval += layout(cb, cl, obj, (struct gpLayout *) msg);
  432.  
  433.       break;
  434.  
  435.    /* experimental code only for my test version */
  436. #ifdef EXPERIMENTAL
  437.    case GM_GOACTIVE:
  438.       {
  439.          struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
  440.  
  441.          if(event->ie_Class == IECLASS_RAWKEY)
  442.          {
  443.             D(bug("goactive->Class %08lx\n",event->ie_Class));
  444.          }
  445.          retval = DoSuperMethodA(cl,obj,msg);
  446.          break;
  447.       }
  448.    case GM_HANDLEINPUT:
  449.       {
  450.          struct InputEvent *event = ((struct gpInput *) msg)->gpi_IEvent;
  451.  
  452.          switch(event->ie_Class)
  453.          {
  454.          case IECLASS_RAWKEY:
  455.             D(bug("handleinput->event->ie_Code : %02lx\n",event->ie_Code));
  456.             break;
  457.          case IECLASS_RAWMOUSE:
  458.             break;
  459.          }
  460.          retval = DoSuperMethodA(cl,obj,msg);
  461.       }
  462.       break;
  463. #endif
  464.    case GM_RENDER:
  465.       bd = INST_DATA(cl,obj);
  466.  
  467. #ifdef EXPERIMENTAL
  468.       {
  469.          APTR gadobj;
  470.  
  471.          retval = DoSuperMethodA(cl,obj,msg);
  472.  
  473.          gadobj = bd->bd_ObjectList.lh_Head;
  474.          D(bug("rport : %lx\n",GPR(msg)->gpr_RPort));
  475.          D(bug("ginfo : %lx\n",GPR(msg)->gpr_GInfo));
  476.          D(bug("redraw: %ld\n",GPR(msg)->gpr_Redraw));
  477.          while((gadobj = NextObject(&gadobj)))
  478.          {
  479.             D(bug("rendering gadobj : %lx\n",gadobj));
  480.             DoMethodA(gadobj,msg);
  481.          }
  482.       }
  483. #endif
  484.  
  485.       {
  486.          struct RastPort *rp = GPR(msg)->gpr_RPort;
  487.          struct DrawInfo *dri = GPR(msg)->gpr_GInfo->gi_DrInfo;
  488.          struct Rectangle rect;
  489.          struct IBox *domain;
  490.          ULONG x,y;
  491.          ULONG ux,uy;
  492.          ULONG py,px,num,grp;
  493.          ULONG topy,topx;
  494.          LONG w,h;
  495.          LONG dx,dy,height;
  496.          LONG chrs;
  497.  
  498.          STRPTR lbuf = bd->bd_LineBuffer;
  499.          STRPTR bptr;
  500.          STRPTR ptr,ptr1;
  501.          STRPTR end;
  502.  
  503.          UBYTE fgpen = (dri) ? dri->dri_Pens[TEXTPEN]       : 1;
  504.          UBYTE bgpen = (dri) ? dri->dri_Pens[BACKGROUNDPEN] : 0;
  505.  
  506.          D(bug("draw mode : %lx\n",GPR(msg)->gpr_Redraw));
  507.  
  508.          if(GetDTAttrs(obj,DTA_TopVert     ,&y,
  509.                            DTA_TopHoriz    ,&x,
  510.                            DTA_VisibleVert ,&h,
  511.                            DTA_VisibleHoriz,&w,
  512.                            DTA_VertUnit    ,&uy,
  513.                            DTA_HorizUnit   ,&ux,
  514.                            DTA_Domain      ,&domain,
  515.                            TAG_DONE) == 7 && lbuf)
  516.          {
  517.             BOOL showascii = (bd->bd_Flags & BDF_SHOWASCII) ||
  518.                              (bd->bd_DisplayHex == BDTDH_NONE);
  519.             UWORD numadd   = (bd->bd_BufferLen > ((1<<16) - 1)) ? 10 : 6;
  520.  
  521.             topy = y;
  522.             topx = x;
  523.  
  524.             height = (h-1) * uy;
  525.  
  526.             rect.MinX = domain->Left;
  527.             rect.MinY = domain->Top;
  528.             rect.MaxX = domain->Left + w * ux - 1;
  529.             rect.MaxY = domain->Top  + h * uy - 1;
  530.  
  531.             SetFont(GPR(msg)->gpr_RPort,bd->bd_Font);
  532.             SetABPenDrMd(rp,fgpen,bgpen,JAM2);
  533.  
  534.             y *= uy;
  535.             x *= ux;
  536.  
  537.             dx = (x - bd->bd_OldX);
  538.             dy = (y - bd->bd_OldY);
  539.  
  540.             bd->bd_OldX = x;
  541.             bd->bd_OldY = y;
  542.  
  543.             if(dx > domain->Width/2 || dx <-domain->Width/2)
  544.                dx = 0;
  545.  
  546.             if(dy > height/2 || dy < -height/2)
  547.                dy = 0;
  548.  
  549.             py = 0;
  550.             px = 0;
  551.  
  552.             if(dx || dy)
  553.                ScrollRasterBF(rp,dx,dy,
  554.                               rect.MinX,rect.MinY,rect.MaxX,rect.MaxY);
  555.  
  556.             D(bug("dx : %ld , dy : %ld\n",dx,dy));
  557.  
  558.             if(dx == 0)
  559.             {
  560.                if(dy < 0)
  561.                   height = -dy;
  562.                else if(dy > 0)
  563.                {
  564.                   py = height - dy;
  565.                   topy += ((domain->Height / uy) - dy/uy);
  566.                }
  567.             } else if(dx > 0)
  568.             {
  569.                px = w * ux - dx;
  570.                topx += (w - (dx/ux));
  571.                w = dx/ux;
  572.             } else
  573.             {
  574.                w = (-dx/ux);
  575.             }
  576.  
  577.             num = topy * bd->bd_BytesPerLine;
  578.             ptr = &bd->bd_Buffer[num];
  579.             end = &bd->bd_Buffer[bd->bd_BufferLen];
  580.  
  581.             D(bug("py : %ld , height : %ld\n",py,height));
  582.  
  583.             for(; py <= height ; py += rp->TxHeight)
  584.             {
  585.                bptr = ptr;
  586.                ptr1 = lbuf;
  587.  
  588.                if(numadd == 10)
  589.                   sprintf(lbuf,"%08lx: ",num);
  590.                else
  591.                   sprintf(lbuf,"%04lx: ",num);
  592.                ptr1 += numadd;
  593.  
  594.                switch(bd->bd_DisplayHex)
  595.                {
  596.                case BDTDH_BYTE:
  597.                   for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
  598.                   {
  599.                      sprintf(ptr1,"%02lx ",*ptr);
  600.                      ptr++;
  601.                      ptr1 += 3;
  602.                   }
  603.  
  604.                   while(grp < bd->bd_NumGroups)
  605.                   {
  606.                      strcpy(ptr1,"   ");
  607.                      ptr1 += 3;
  608.                      ptr++;
  609.                      grp++;
  610.                   }
  611.                   break;
  612.                case BDTDH_WORD:
  613.                   for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
  614.                   {
  615.                      sprintf(ptr1,"%04lx ",*((UWORD *) ptr));
  616.                      ptr += sizeof(UWORD);
  617.                      ptr1 += 5;
  618.                   }
  619.  
  620.                   while(grp < bd->bd_NumGroups)
  621.                   {
  622.                      strcpy(ptr1,"     ");
  623.                      ptr1 += 5;
  624.                      ptr += sizeof(UWORD);
  625.                      grp++;
  626.                   }
  627.                   break;
  628.                case BDTDH_LONG:
  629.                   for(grp = 0 ; grp < bd->bd_NumGroups && ptr < end ; grp++)
  630.                   {
  631.                      sprintf(ptr1,"%08lx ",*((ULONG *) ptr));
  632.                      ptr += sizeof(ULONG);
  633.                      ptr1 += 9;
  634.                   }
  635.  
  636.                   while(grp < bd->bd_NumGroups)
  637.                   {
  638.                      strcpy(ptr1,"         ");
  639.                      ptr1 += 9;
  640.                      ptr += sizeof(ULONG);
  641.                      grp++;
  642.                   }
  643.                   break;
  644.                default:
  645.                   ptr += bd->bd_BytesPerLine;
  646.                }
  647.  
  648.                /* write ASCII string */
  649.                if(showascii)
  650.                {
  651.                   while(bptr < ptr && bptr < end)
  652.                   {
  653.                      if(*bptr < 32)
  654.                         *ptr1 = '.';
  655.                      else
  656.                         *ptr1 = *bptr;
  657.                      ptr1++;
  658.                      bptr++;
  659.                   }
  660.  
  661.                   while(bptr < ptr)
  662.                   {
  663.                      *ptr1++ = ' ';
  664.                      bptr++;
  665.                   }
  666.                }
  667.  
  668.                chrs = MIN((ptr1 - lbuf) - topx,w);
  669.                if(chrs > 0)
  670.                {
  671.                   Move(rp,domain->Left + px,domain->Top + py + rp->TxBaseline);
  672.                   Text(rp,&lbuf[topx],chrs);
  673.                }
  674.  
  675.                num += bd->bd_BytesPerLine;
  676.             }
  677.          }
  678.       }
  679.       retval = DoSuperMethodA(cl,obj,msg);
  680.       break;
  681.    case DTM_WRITE:
  682.       bd = INST_DATA(cl,obj);
  683.  
  684.       switch(WRMSG(msg)->dtw_Mode)
  685.       {
  686.       case DTWM_RAW:
  687.          D(bug("dtWrite Rawmode : filehandle %lx !\n",WRMSG(msg)->dtw_FileHandle));
  688.          D(bug("attrs at : %lx\n",WRMSG(msg)->dtw_AttrList));
  689.          D({
  690.                struct TagItem *tstate = WRMSG(msg)->dtw_AttrList;
  691.                struct TagItem *tag;
  692.  
  693.                while((tag = NextTagItem(&tstate)))
  694.                   bug("{%08lx,%ld}\n",tag->ti_Tag,tag->ti_Data);
  695.            });
  696.  
  697.          Write(WRMSG(msg)->dtw_FileHandle,bd->bd_Buffer,bd->bd_BufferLen);
  698.          retval = 1;
  699.          break;
  700.       default:
  701.          retval = DoSuperMethodA(cl,obj,msg);
  702.       }
  703.       break;
  704.    default:
  705.       retval = DoSuperMethodA(cl,obj,msg);
  706.    }
  707.  
  708.    return(retval);
  709. }
  710. /*FE*/
  711.  
  712. /*FS*/ ULONG getattr(Class *cl,Object *obj,struct opGet *msg)
  713. {
  714.    struct BinaryData *bd = INST_DATA(cl,obj);
  715.    ULONG *storage = msg->opg_Storage;
  716.  
  717.    switch(msg->opg_AttrID)
  718.    {
  719.    case DTA_TextFont:
  720.       *storage = (ULONG) bd->bd_Font;
  721.       break;
  722.    case DTA_TextAttr:
  723.       *storage = (ULONG) &bd->bd_TextAttr;
  724.       break;
  725.    case DTA_Methods:
  726.       *storage = (ULONG) methods;
  727.       break;
  728.    case BDTA_Buffer:
  729.       *storage = (ULONG) bd->bd_Buffer;
  730.       break;
  731.    case BDTA_BufferLen:
  732.       *storage = (ULONG) bd->bd_BufferLen;
  733.       break;
  734.    case BDTA_BytesPerLine:
  735.       *storage = (ULONG) bd->bd_BytesPerLine;
  736.       break;
  737.    case BDTA_DisplayHex:
  738.       *storage = (ULONG) bd->bd_DisplayHex;
  739.       break;
  740.    case BDTA_ShowASCII:
  741.       *storage = (ULONG) ((bd->bd_Flags & BDF_SHOWASCII) == BDF_SHOWASCII);
  742.       break;
  743.    case BDTA_DisplayWrap:
  744.       *storage = (ULONG) ((bd->bd_Flags & BDF_DISPLAYWRAP) == BDF_DISPLAYWRAP);
  745.       break;
  746.    default:
  747.       return(0);
  748.    }
  749.    return(1);
  750. }
  751. /*FE*/
  752.  
  753. /*FS*/ ULONG setattrs(Class *cl,Object *obj,struct opSet *msg)
  754. {
  755.    struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  756.    struct BinaryData *bd = INST_DATA(cl,obj);
  757.  
  758.    struct TagItem *tstate = msg->ops_AttrList;
  759.    struct TagItem *tag;
  760.  
  761.    ULONG retval = 0;
  762.    ULONG tidata;
  763.  
  764.    while((tag = NextTagItem(&tstate)))
  765.    {
  766.       tidata = tag->ti_Data;
  767.  
  768.       retval++;
  769.       switch(tag->ti_Tag)
  770.       {
  771.       case DTA_TextAttr:
  772.          {
  773.             struct TextFont *font;
  774.  
  775.             if((font = OpenFont((struct TextAttr *) tidata)))
  776.             {
  777.                /* only use fixed width fonts */
  778.                if(font->tf_Flags & FPF_PROPORTIONAL)
  779.                {
  780.                   CloseFont(font);
  781.                   useDefaultFont(cb,bd);
  782.                } else
  783.                {
  784.                   bd->bd_TextAttr = *((struct TextAttr *) tidata);
  785.                   bd->bd_TextAttr.ta_Name = bd->bd_FontName;
  786.                   strcpy(bd->bd_FontName,((struct TextAttr *) tidata)->ta_Name);
  787.  
  788.                   if(bd->bd_Font)
  789.                      CloseFont(bd->bd_Font);
  790.  
  791.                   bd->bd_Font = font;
  792.                }
  793.             } else
  794.                retval--;
  795.          }
  796.          break;
  797.       case BDTA_Buffer:
  798.          {
  799.             ULONG len = GetTagData(BDTA_BufferLen,0,msg->ops_AttrList);
  800.  
  801.             if(tidata && len)
  802.             {
  803.                if((bd->bd_Buffer) && (bd->bd_Flags & BDF_ALLOCATED))
  804.                   FreeMem(bd->bd_Buffer,bd->bd_BufferLen);
  805.  
  806.                bd->bd_Flags &= ~BDF_ALLOCATED;
  807.  
  808.                bd->bd_Buffer    = (UBYTE *) tidata;
  809.                bd->bd_BufferLen = len;
  810.  
  811.                retval++;
  812.             } else
  813.                retval--;
  814.          }
  815.          break;
  816.       case BDTA_BytesPerLine:
  817.          if(tag->ti_Data != bd->bd_BytesPerLine)
  818.             bd->bd_BytesPerLine = (UWORD) tag->ti_Data;
  819.          else
  820.             retval--;
  821.          break;
  822.       case BDTA_DisplayHex:
  823.          if(tag->ti_Data != bd->bd_DisplayHex)
  824.             bd->bd_DisplayHex   = (UWORD) tag->ti_Data;
  825.          else
  826.             retval--;
  827.          break;
  828.       case BDTA_ShowASCII:
  829.          if(tag->ti_Data)
  830.             bd->bd_Flags |= BDF_SHOWASCII;
  831.          else
  832.             bd->bd_Flags &= ~BDF_SHOWASCII;
  833.          break;
  834.       case BDTA_DisplayWrap:
  835.          if(tag->ti_Data)
  836.             bd->bd_Flags |= BDF_DISPLAYWRAP;
  837.          else
  838.             bd->bd_Flags &= ~BDF_DISPLAYWRAP;
  839.          break;
  840.       default:
  841.          retval--;
  842.       }
  843.    }
  844.  
  845.    return(retval);
  846. }
  847. /*FE*/
  848.  
  849. /*FS*/ GetA4 ULONG layout(struct ClassBase *cb, Class * cl, Object * obj, struct gpLayout * gpl)
  850. {
  851.    struct DTSpecialInfo *si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
  852.    struct BinaryData *bd = INST_DATA(cl,obj);
  853.  
  854.    /* Attributes obtained from super-class */
  855.  
  856.    struct TextFont *font = bd->bd_Font;
  857.    struct IBox *domain;
  858.  
  859.    ULONG retval = 0;
  860.  
  861.    ENTERING;
  862.  
  863.    /* Get all the attributes that we are going to need for a successful layout */
  864.    if((GetDTAttrs(obj,DTA_Domain,      (ULONG) &domain,
  865.                       TAG_DONE) == 1))
  866.    {
  867.       /* Lock the global object data so that nobody else can manipulate it */
  868.       ObtainSemaphore (&(si->si_Lock));
  869.  
  870. #ifdef EXPERIMENTAL
  871.       {
  872.          APTR gadobj;
  873.          /* dispose all objects from the list c*/
  874.          gadobj = bd->bd_ObjectList.lh_Head;
  875.          while((gadobj = NextObject(&gadobj)))
  876.          {
  877.             DoMethod(gadobj,OM_REMOVE);
  878.             if(G(gadobj)->GadgetRender)
  879.                DoMethod(G(gadobj)->GadgetRender,OM_DISPOSE);
  880.             DoMethod(gadobj,OM_DISPOSE);
  881.          }
  882.  
  883.          {
  884.             Object *image;
  885.             if((image = NewObject(NULL,"frameiclass",IA_Left     ,20 /* domain->Left   + 4 */,
  886.                                                      IA_Top      ,20 /* domain->Top    + 1 */,
  887.                                                      IA_Width    ,100 /* domain->Width  - 8 */,
  888.                                                      IA_Height   ,10 /* font->tf_YSize + 4 */,
  889.                                                      IA_FrameType,FRAME_BUTTON,
  890.                                                      TAG_DONE)))
  891.                if((gadobj = NewObject(NULL,"gadgetclass",GA_Left   ,20 /* domain->Left   + 4 */,
  892.                                                          GA_Top    ,20 /* domain->Top    + 1 */,
  893.                                                          GA_Width  ,100 /* domain->Width  - 8 */,
  894.                                                          GA_Height ,10 /* font->tf_YSize + 4 */,
  895.                                                          GA_ID     , 1,
  896.                                                          GA_Image  ,image,
  897.                                                          TAG_DONE)))
  898.                {
  899.                   DoMethod(gadobj,GM_LAYOUT,gpl->gpl_GInfo,TRUE);
  900.                   DoMethod(gadobj,OM_ADDTAIL,&bd->bd_ObjectList);
  901.                } else
  902.                   DoMethod(image,OM_DISPOSE);
  903.          }
  904.       }
  905. #endif
  906.  
  907.       retval = si->si_TotVert;
  908.  
  909.       /* We only need to perform layout if we are doing word wrap, or this
  910.        * is the initial layout call */
  911.       if(gpl->gpl_Initial || (bd->bd_Flags & BDF_DISPLAYWRAP))
  912.       {
  913.          const UBYTE displayhexbytes[]   = {0,3,5,9};
  914.          const UBYTE displayasciibytes[] = {1,1,2,4};
  915.  
  916.          ULONG numgroups;
  917.          ULONG bytesperline;
  918.          ULONG lines;
  919.          ULONG displayaddr = (bd->bd_BufferLen >= (1<<16)) ? 10 : 6;
  920.          ULONG showascii;
  921.  
  922.          showascii = ((bd->bd_Flags & BDF_SHOWASCII) || bd->bd_DisplayHex == BDTDH_NONE) ? 1 : 0;
  923.  
  924.          numgroups    =
  925.          bytesperline = bd->bd_BytesPerLine;
  926.  
  927.          if(bd->bd_DisplayHex)
  928.             numgroups >>= (bd->bd_DisplayHex - 1);
  929.  
  930.          /* Note this wrap function doesn't work right with proportional fonts !* */
  931.          if(bd->bd_Flags & BDF_DISPLAYWRAP)
  932.          {
  933.             ULONG chars = domain->Width / bd->bd_Font->tf_XSize;
  934.  
  935.             D(bug("object width : %ld\n",domain->Width));
  936.             D(bug("font width   : %ld\n",font->tf_XSize));
  937.             D(bug("chars        : %ld\n",chars));
  938.  
  939.             bytesperline =
  940.             numgroups    = (chars - displayaddr - showascii) / (displayhexbytes[bd->bd_DisplayHex] +
  941.                                                                 ((showascii) ? displayasciibytes[bd->bd_DisplayHex] : 0));
  942.  
  943.             if(bd->bd_DisplayHex)
  944.                bytesperline = (numgroups) << (bd->bd_DisplayHex - 1);
  945.          }
  946.  
  947.          if(bytesperline < 4)
  948.          {
  949.             bytesperline  = 4;
  950.             numgroups     = bytesperline / displayasciibytes[bd->bd_DisplayHex];
  951.          }
  952.  
  953.  
  954.          lines = (bd->bd_BufferLen / bytesperline) + ((bd->bd_BufferLen % bytesperline) ? 1 : 0) - 1;
  955.  
  956.          bd->bd_LineBytes = displayaddr + numgroups * displayhexbytes[bd->bd_DisplayHex] +
  957.                             ((showascii) ? bytesperline : 0) + 1;
  958.          bd->bd_NumGroups    = numgroups;
  959.          bd->bd_BytesPerLine = bytesperline;
  960.  
  961.          if(bd->bd_LineBuffer && bd->bd_LineBytes > bd->bd_LineBufferLen)
  962.          {
  963.             FreeMem(bd->bd_LineBuffer,bd->bd_LineBufferLen);
  964.             bd->bd_LineBuffer = NULL;
  965.          }
  966.  
  967.          if(!bd->bd_LineBuffer)
  968.          {
  969.             bd->bd_LineBufferLen = bd->bd_LineBytes;
  970.             bd->bd_LineBuffer    = AllocMem(bd->bd_LineBufferLen,MEMF_ANY);
  971.          }
  972.  
  973.          /* Compute the lines and columns type information */
  974.          si->si_VertUnit  = font->tf_YSize;
  975.          si->si_VisVert   = domain->Height / si->si_VertUnit;
  976.          si->si_TotVert   = lines;
  977.  
  978.          si->si_HorizUnit = font->tf_XSize;
  979.          si->si_VisHoriz  = domain->Width / font->tf_XSize;
  980.          si->si_TotHoriz  = bd->bd_LineBytes;
  981.  
  982.          /* Release the global data lock */
  983.          ReleaseSemaphore(&si->si_Lock);
  984.  
  985.          retval = lines;
  986.  
  987.          if(gpl->gpl_Initial)
  988.          {
  989.             struct RastPort *rp;
  990.  
  991.             /* Get a pointer to the rastport */
  992.             if((rp = ObtainGIRPort (gpl->gpl_GInfo)))
  993.             {
  994.                struct gpRender gpr;
  995.  
  996.                /* Force a redraw */
  997.                gpr.MethodID   = GM_RENDER;
  998.                gpr.gpr_GInfo  = gpl->gpl_GInfo;
  999.                gpr.gpr_RPort  = rp;
  1000.                gpr.gpr_Redraw = GREDRAW_REDRAW;
  1001.                DoMethodA (obj, (Msg) &gpr);
  1002.  
  1003.                /* Release the temporary rastport */
  1004.                ReleaseGIRPort (rp);
  1005.             }
  1006.          }
  1007.       }
  1008.       /* Not aborted, so tell the world of our newest attributes */
  1009.       notifyAttrChanges (obj, gpl->gpl_GInfo, NULL,
  1010.                          GA_ID,                   G(obj)->GadgetID,
  1011.  
  1012.                          DTA_VisibleVert,         domain->Height / font->tf_YSize,
  1013.                          DTA_TotalVert,           retval,
  1014.                          DTA_NominalVert,         font->tf_YSize * 25,
  1015.                          DTA_VertUnit,            font->tf_YSize,
  1016.  
  1017.                          DTA_VisibleHoriz,        domain->Width / font->tf_XSize,
  1018.                          DTA_TotalHoriz,          bd->bd_LineBytes,
  1019.                          DTA_NominalHoriz,        font->tf_XSize * 80,
  1020.                          DTA_HorizUnit,           font->tf_XSize,
  1021.  
  1022.                          DTA_Title,               bd->bd_Name,
  1023.                          DTA_Busy,                FALSE,
  1024.                          DTA_Sync,                TRUE,
  1025.                          TAG_DONE);
  1026.  
  1027.    }
  1028.  
  1029.    LEAVING;
  1030.  
  1031.    return(retval);
  1032. }
  1033. /*FE*/
  1034.  
  1035.